package com.yj.auto.core.jfinal.base;

import java.util.List;
import java.util.Map;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import com.yj.auto.Constants;
import com.yj.auto.core.base.model.QueryModel;
import com.yj.auto.core.web.system.service.AttaService;
import com.yj.auto.helper.AutoHelper;

/**
 * BaseService
 */
public abstract class BaseService<T extends BaseEntity> {
	public abstract T getDao();

	/**
	 * 根据主键查找对象
	 * 
	 * @param id
	 *            主键
	 * @return
	 */
	public T get(Integer id) {
		return (T) getDao().findById(id);
	}

	/**
	 * 保存对象
	 * 
	 * @param model
	 * @return
	 */
	public boolean save(T model) {
		boolean success = model.save();
		this.updateOrDelAtta(model);
		return success;
	}

	/**
	 * 更新对象
	 * 
	 * @param model
	 * @return
	 */
	public boolean update(T model) {
		this.updateOrDelAtta(model);
		return model.update();
	}

	/**
	 * 查询列表
	 * 
	 * @param key
	 *            sql name
	 * @param query
	 *            查询参数
	 * @return
	 */
	public List<T> find(String key, QueryModel query) {
		SqlPara sqlPara = getSqlPara(key, query);
		return find(sqlPara);
	}

	public List<T> find(SqlPara sqlPara) {
		return getDao().find(sqlPara);
	}

	public List<T> find(QueryModel query) {
		SqlPara sql = getListSqlPara(query);
		return find(sql);
	}

	/**
	 * 列表-分页查询
	 * 
	 * @param query
	 * @return
	 */
	public Page<T> paginate(QueryModel query) {
		SqlPara sql = getListSqlPara(query);
		Page<T> page = getDao().paginate(query.getPage(), query.getSize(), sql);
		return page;
	}

	/**
	 * SQL对象
	 * 
	 * @param key
	 *            sql name
	 * @param query
	 *            查询参数
	 * @return
	 */
	public SqlPara getSqlPara(String key, QueryModel query) {
		SqlPara sql = Db.getSqlPara(key, query);
		return sql;
	}

	/**
	 * 获取分页动态SQL
	 * 
	 * @return
	 */
	public abstract SqlPara getListSqlPara(QueryModel query);

	protected Map<String, Integer[][]> getAttaMap(Model model) {
		Map<String, Integer[][]> files = (Map<String, Integer[][]>) model.get(Constants.MODEL_ATTA_MAP);
		return files;
	}

	protected Integer[][] getAttas(Model model, String attaType) {
		Map<String, Integer[][]> map = getAttaMap(model);
		Integer[][] attas = null;
		if (null != map) {
			attas = map.get(attaType);
		}
		return attas;
	}

	/**
	 * 更新此记录相应的附件信息
	 * 
	 * @param model
	 * @return
	 */
	protected boolean updateOrDelAtta(T model) {
		Map<String, Integer[][]> files = getAttaMap(model);
		Integer dataId = model.getInt(model.getTablePK());
		if (null == dataId || null == files || files.isEmpty())
			return false;
		return updateOrDelAtta(dataId, files);
	}

	/**
	 * 更新此记录相应的附件信息
	 * 
	 * @param dataId
	 *            业务主键
	 * @param files
	 *            文件信息
	 * @return
	 */
	public boolean updateOrDelAtta(Integer dataId, Map<String, Integer[][]> files) {
		if (null == dataId || null == files || files.isEmpty())
			return false;
		boolean success = true;
		AttaService attSrv = AutoHelper.getAttaService();
		for (Map.Entry<String, Integer[][]> entry : files.entrySet()) {
			String dataType = entry.getKey();
			Integer[][] temp = entry.getValue();
			if (null == temp || temp.length < 1)
				continue;
			Integer[] adds = temp[0];
			Integer[] dels = null;
			if (temp.length > 1) {
				dels = temp[1];
			}
			if (null != dels && dels.length > 0) {
				// success = success && attSrv.delete(dels);
				attSrv.delete(dels);
			}
			if (null != adds && adds.length > 0) {
				// success = success && attSrv.updateAttaData(dataType, dataId,
				// adds);
				attSrv.updateAttaData(dataType, dataId, adds);
			}
		}
		return success;
	}

	/**
	 * 删除附件
	 * 
	 * @param id
	 *            数据主键
	 * @param attaType
	 *            所有关联附件类型
	 */
	protected void deleteAtta(Integer id, String... attaType) {
		if (null == id || null == attaType || attaType.length < 1)
			return;
		AttaService attaSrv = AutoHelper.getAttaService();
		for (String type : attaType) {
			attaSrv.delete(type, id);
		}
	}

	/**
	 * 根据主键删除对象
	 * 
	 * @param ids
	 *            主键集合
	 * @return
	 */
	public boolean delete(Integer... ids) {
		boolean success = delete(ids, new String[0]);
		return success;
	}

	/**
	 * 
	 * 根据主键删除对象，如果有附件数据，同时删除文件
	 * 
	 * @param ids
	 *            主键集合
	 * @param attaType
	 *            附件数据类型
	 * @return
	 */
	protected boolean delete(Integer[] ids, String... attaType) {
		if (null == ids || ids.length < 1)
			return false;
		if (null != attaType && attaType.length > 0) {
			for (Integer id : ids) {
				deleteAtta(id, attaType);
			}
		}
		if (ids.length == 1) {
			return deleteById(ids[0]);
		} else {
			return getDao().deleteByColumn(getDao().getTablePK(), ids);
		}
	}

	/**
	 * 根据主键删除对象
	 * 
	 * @param id
	 *            主键
	 * @return
	 */
	public boolean deleteById(Integer id) {
		boolean success = deleteById(id, new String[0]);
		return success;
	}

	protected boolean deleteById(Integer id, String... attaType) {
		if (null == id)
			return false;
		if (null != attaType && attaType.length > 0) {
			deleteAtta(id, attaType);
		}
		return getDao().deleteById(id);
	}
}
